import json
import logging
import time

from flask import request
from werkzeug.datastructures import Headers

from yolo_web import app, baichuan, commodities, db


@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"


@app.route("/chat", methods=["POST", "GET"])
def chat():
    # 处理参数
    message = ""
    stream = 0
    if request.is_json:
        body = request.get_json()
        message = body["message"]
        stream = int(body["stream"])
    elif request.method == "POST":
        message = request.form["message"]
        stream = int(request.form["stream"])
    else:
        message = request.args.get("message", "")
        stream = int(request.args.get("stream", 0))
    app.logger.info(f"message: {message}, stream: {stream}")
    if len(message) == 0:
        return ("参数错误", 400)

    if stream == 1:

        def generate():
            response = baichuan.do_request(message, True)
            for line in response.iter_lines():
                if line:
                    yield line.decode("utf-8") + "\n"

        return app.response_class(generate())

    start_time = time.time()
    response = baichuan.do_request(message, False)
    app.logger.info("cost: {:.2f} seconds".format(time.time() - start_time))

    result = ""
    if response.status_code == 200:
        app.logger.info(
            "request success，X-BC-Request-Id: %s",
            response.headers.get("X-BC-Request-Id"),
        )
        for line in response.iter_lines():
            if line:
                result += line.decode("utf-8")
    else:
        app.logger.info("request fail. status code is: %d", response.status_code)
        app.logger.info("request fail. body is: %s", response.text)
        app.logger.info(
            "request fail. X-BC-Request-Id: %s", response.headers.get("X-BC-Request-Id")
        )
    app.logger.info("result is: %s", result)
    return (
        result,
        response.status_code,
        Headers([("Content-Type", response.headers.get("Content-Type"))]),
    )


@app.route("/rec", methods=["POST", "GET"])
def rec():
    if request.method == "POST":
        category = request.form["category"]
    else:
        category = request.args.get("category", "")
    if len(category) == 0:
        return ("参数错误", 400)

    for key in commodities.commodities:
        if category in key:
            data = commodities.commodities[key]
    return (
        json.dumps({"data": data}, default=lambda o: o.__dict__, ensure_ascii=False),
        Headers([("Content-Type", "application/json;charset=UTF-8")]),
    )


@app.route("/q", methods=["POST", "GET"])
def queryWord():
    if request.method == "POST":
        word = request.form["word"]
        scene = request.form["scene"]
        clean = request.form["clean"]
    else:
        word = request.args.get("word", "")
        scene = request.args.get("scene", "")
        clean = request.args.get("clean", "")
    if len(word) == 0:
        return ("参数错误", 400)

    if clean != "y":
        # 查看是否缓存
        wordResult = db.query_db(
            "select * from words where word=? and scene=? order by word desc",
            [word, scene],
            one=True,
        )
        app.logger.info("query result from db: %s", wordResult)
        if wordResult:
            return (
                json.dumps(
                    {
                        "data": wordResult[2],
                    },
                    ensure_ascii=False,
                ),
                Headers([("Content-Type", "application/json")]),
            )
    else:
        db.update_db("delete from words where word=?", [word])

    message = "将单词 " + word + " 翻译成中文，只说出一个高频意思即可。"
    if len(scene):
        message = "在" + scene + "场景下，" + message
    app.logger.info("word: %s, scene: %s, messsage: %s", word, scene, message)

    # 发请求
    start_time = time.time()
    response = baichuan.do_request(message, False)
    app.logger.info("cost: {:.2f} seconds".format(time.time() - start_time))

    result = ""
    if response.status_code == 200:
        app.logger.info(
            "request success，X-BC-Request-Id: %s",
            response.headers.get("X-BC-Request-Id"),
        )
        for line in response.iter_lines():
            if line:
                result += line.decode("utf-8")
    else:
        app.logger.info("request fail. status code is: %d", response.status_code)
        app.logger.info("request fail. body is: %s", response.text)
        app.logger.info(
            "request fail. X-BC-Request-Id: %s", response.headers.get("X-BC-Request-Id")
        )
    app.logger.info("result is: %s", result)

    a = json.loads(result)
    meaning = a["choices"][0]["message"]["content"]

    # 保存到数据库
    db.update_db("insert into words values(?, ?, ?)", [word, scene, meaning])
    return (
        json.dumps(
            {
                "data": meaning,
            },
            ensure_ascii=False,
        ),
        Headers([("Content-Type", "application/json")]),
    )


@app.route("/words", methods=["POST", "GET", "DELETE"])
def words():
    if request.method == "GET":
        return db.query_db("select * from words")

    if request.method == "POST":
        word = request.form["word"]
        scene = request.form["scene"]
        meaning = request.form["meaning"]
        db.update_db("insert into words values(?, ?, ?)", [word, scene, meaning])
        return db.query_db("select * from words")

    if request.method == "DELETE":
        word = request.form["word"]
        scene = request.form["scene"]
        db.update_db("delete from words where word=? and scene=?", [word, scene])
        return db.query_db("select * from words")
    return ""


if __name__ != "__main__":
    # 解决 gunicorn 不打印 flask 日志的问题
    # https://cloud.tencent.com/developer/article/1688483
    gunicorn_logger = logging.getLogger("gunicorn.error")
    app.logger.handlers = gunicorn_logger.handlers
    app.logger.setLevel(gunicorn_logger.level)
